#include "CBattleRoundCtrl.h"
#include "CBattleVideo.h"
#include "CBattleInf.h"
#include "CBattleRandom.h"

template<>
bool CRankArray<CBattleRoundUnit, MAX_BATTLE_ROLES>::IsSame(
        CBattleRoundUnit& stA, CBattleRoundUnit& stB) const
{
    return (stA.GetRoleID() == stB.GetRoleID());
}

template<>
int CRankArray<CBattleRoundUnit, MAX_BATTLE_ROLES>::CmpFunc(
        CBattleRoundUnit& stA, CBattleRoundUnit& stB) const
{
    if (stA.GetOrder() > stB.GetOrder())
    {
        return 1;
    }
    else if (stA.GetOrder() < stB.GetOrder())
    {
        return -1;
    }
    else
    {
        if (stA.GetPos() > stB.GetPos())
        {
            return 1;
        }
        else if (stA.GetPos() < stB.GetPos())
        {
            return -1;
        }
        else
        {
            if (CBattleRandom::GetRand(MAX_BATTLE_DATA_PRECISION) % 2)
            {
                return 1;
            }
            else 
            {
                return -1;
            }
        }
    }

    return 0;
}

int CBattleRoundCtrl::InitRoundCtrl() 
{
    int iRet = 0;

    BATTLE_INF->_pstRoundCtrl->Clear(); //必须初始化

    //将角色放到对应位置
    iRet = BATTLE_INF->_pstRoles->InitBattleRoundCtrl();
    CT_RETURN(iRet);

#if 0
    //2013-06-09 修改
    //确定总体出手顺序
    bool bIsLeftFirst = false;
    iRet = BATTLE_INF->_pstRoles->GetTotalTurnOrder(bIsLeftFirst);
    CT_RETURN(iRet);

    if (bIsLeftFirst)
    {
        for (int i = 0; i < _astRoleStats.Size(); ++i)
        {
            _astRoleStats[i]._bAfirst = true;
        }
    }
    else
    {
        for (int i = 0; i < _astRoleStats.Size(); ++i)
        {
            _astRoleStats[i]._bAfirst = false;
        }
    }

    //整理一下数据 这个接口并不快 不过要保证已定的出手顺序
    for (int i = 0; i < _astRoleStats.Size(); )
    {
        if ((!_astRoleStats[i]._stRoleA._bHasRole) && (!_astRoleStats[i]._stRoleB._bHasRole))
        {
            iRet = _astRoleStats.ShiftDelOneItem(i);
            if (iRet < 0)
            {
                return RET_SYSTEM_FAIL;
            }
        }
        else
        {
            ++i;
        }
    }
#else
    //使用CRankArray进行优化
    _astRoleStats.Clear();
    CBattleRolePareData stPareTmp;
    for (int i = 0; i < _astStatRank.Size(); )
    {
        stPareTmp.Clear();
        stPareTmp._bAfirst = true;
        stPareTmp._stRoleA._bHasRole = true;
        stPareTmp._stRoleA._iRoleID = _astStatRank[i]._iRoleID;
        ++i;
        if (i < _astStatRank.Size())
        {
            stPareTmp._stRoleB._bHasRole = true;
            stPareTmp._stRoleB._iRoleID = _astStatRank[i]._iRoleID;
            ++i;
        }

        _astRoleStats.AddOneItem(stPareTmp);
    }
#endif
    
    //初始化战斗统计信息
    BATTLE_INF->_pstRules->InitBattleInfoCount();

    return 0;
}

int CBattleRoundCtrl::InitAddRole(CBattleRole& stBattleRole)
{
    int iTurnOrder = stBattleRole.GetAtkOrder();

    if (iTurnOrder >= MAX_BATTLE_ROLES_PER_SIDE || iTurnOrder < 0)
    {
        return ERROR_BATTLE_TURN_ORDER;
    }

    //InitRoundCtrl接口后面会重置_astRoleStats这里赋值为了校验一个萝卜一个坑
    //规定：stRoleA只放左方 stRoleB只放右方
    if (stBattleRole.IsLeft())
    {
        if (_astRoleStats[iTurnOrder]._stRoleA._bHasRole)
        {
            CT_BATTLE(("Left Role(%d) and Role(%d) has the same order(%d)",
                        _astRoleStats[iTurnOrder]._stRoleA.GetRoleID(),
                        stBattleRole.GetRoleID(), iTurnOrder));
            return ERROR_BATTLE_TURN_ORDER;
        }
    }
    else
    {
        if (_astRoleStats[iTurnOrder]._stRoleB._bHasRole)
        {
            CT_BATTLE(("Right Role(%d) and Role(%d) has the same order(%d)",
                        _astRoleStats[iTurnOrder]._stRoleB.GetRoleID(),
                        stBattleRole.GetRoleID(), iTurnOrder));
            return ERROR_BATTLE_TURN_ORDER;
        }
    }

    //赋值
    if (stBattleRole.IsLeft())
    {
        _astRoleStats[iTurnOrder]._stRoleA._bHasRole = true;
        _astRoleStats[iTurnOrder]._stRoleA._iRoleID = stBattleRole.GetRoleID();
    }
    else
    {
        _astRoleStats[iTurnOrder]._stRoleB._bHasRole = true;
        _astRoleStats[iTurnOrder]._stRoleB._iRoleID = stBattleRole.GetRoleID();
    }

    CBattleRoundUnit stRoundUnit;
    stRoundUnit._bLeft = stBattleRole.IsLeft();
    stRoundUnit._iRoleID = stBattleRole.GetRoleID();
    stRoundUnit._iOrder = stBattleRole.GetTurnOrderValue();
    stRoundUnit._iPos = stBattleRole.GetOriginalPos();

    _astStatRank.Update(stRoundUnit);

    return 0;
}

int CBattleRoundCtrl::NextTurn()
{
    int iRet = 0;
    int iRoleID = 0;

    for (int i = 0; i < _astRoleStats.Size(); ++i)
    {
        CBattleRoundRoleData stRoundRoleData;
        if (_astRoleStats[i].IsCanDoTurn(_iRoundNum, stRoundRoleData))
        {
            iRoleID = stRoundRoleData.GetRoleID();
            CT_BATTLE(("角色(%d)获得本次出手机会", iRoleID));
            CBattleRole stRole;
            iRet = BATTLE_INF->_pstRoles->GetRole(iRoleID, stRole);
            CT_RETURN(iRet);
        
            if (stRole.HasDead())
            {
                CT_BATTLE(("角色(%d)已死亡", iRoleID));
                stRoundRoleData._bHasRole = false;

                return NextTurn();
            }

            CBattleAction stAction;
            stAction._iActionID = CBattleAction::ACTION_GET_TURN;
            stAction._iA = iRoleID;
            
            iRet = BATTLE_INF->_pstActionCtrl->AddAction(stAction);
            CT_RETURN(iRet);

            _bLastTurnIsLeft = stRole.IsLeft();

            return 0;
        }
    }

    _iRoundNum++;
    SetCircleEnd(true);

    return NextTurn();
}

void CBattleRoundCtrl::DumpRoundCtrlInfo()
{
    CT_BATTLE(("%s", "---- BeginRoundCtrl ----"));
    CT_BATTLE(("%-18s = %d", "RoundNum", _iRoundNum));
    CT_BATTLE(("%-18s = %d", "LastTurnIsLeft", _bLastTurnIsLeft));

    CT_BATTLE(("Role Pare Data Size (%d)", _astRoleStats.Size()));
    for (int i = 0; i < _astRoleStats.Size(); ++i)
    {
        CT_BATTLE(("Role Pare Data Index (%d)", i));
        _astRoleStats[i].DumpRolePareInfo();
    }
    CT_BATTLE(("%s", "---- EndRoundCtrl ----"));
}

void CBattleRolePareData::DumpRolePareInfo()
{
    CT_BATTLE(("%s", "-- Round Role A --"));
    _stRoleA.DumpRoundRoleInfo();
    CT_BATTLE(("%s", "-- Round Role B --"));
    _stRoleB.DumpRoundRoleInfo();
    CT_BATTLE(("%-18s = %d", "Afirst", _bAfirst));
}

void CBattleRoundRoleData::DumpRoundRoleInfo()
{
    CT_BATTLE(("%-18s = %d", "HasRole", _bHasRole));
    CT_BATTLE(("%-18s = %d", "RoleID", _iRoleID));
    CT_BATTLE(("%-18s = %d", "LastRoundID", _iLastRoundID));
}
